package stock;

import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;

import misc.Helpers;

import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlTable;
import com.gargoylesoftware.htmlunit.html.HtmlTableDataCell;

public class Stock {

    private final int id;
    private String name;
    private final BlockingDeque<String> deque;

    public Stock(int id) {
        this.id = id;
        deque = new LinkedBlockingDeque<String>();
    }

    public int getId() {
        return id;
    }

    public String waitForName() {
        try {
            return deque.take();
        } catch (InterruptedException ex) {
        }
        return null;
    }

    /**
     * Gets sales from the page with sales only
     * 
     * @param wc
     * @param urlTemplate
     * @return
     * @throws FailingHttpStatusCodeException
     * @throws IOException
     */
    public List<Sale> getAvanzaSales(HtmlPage p)
            throws FailingHttpStatusCodeException, IOException {

        name = ((HtmlTableDataCell) p
                .getByXPath(
                        "/html/body/table/tbody/tr[1]/td[1]/table[@class='tablecontent']/tbody/tr/td/table[1]/tbody/tr/td[@class='greydark11']")
                .get(0)).asText().replaceFirst("Avslut", "");
        name = Helpers.formatName(name);
        deque.add(name);

        // Gets "senaste avslut" table
        HtmlTable table = (HtmlTable) p
                .getByXPath(
                        "/html/body/table/tbody/tr[1]/td[1]/table[@class='tablecontent']/tbody/tr/td/table[2]")
                .get(0);

        List<Sale> sales = new ArrayList<Sale>();
        Sale lastAddedSale = null;
        for (int i = 1; i < table.getRowCount(); i++) {
            try {
                long time = calculateDate(table.getCellAt(i, 3).asText());
                long amount = Long.parseLong(table.getCellAt(i, 5).asText());
                double price = Double.parseDouble(table.getCellAt(i, 4)
                        .asText().replace(',', '.'));

                // If already exists at that time
                if (lastAddedSale != null && lastAddedSale.getTime() == time) {
                    lastAddedSale.addAmount(amount);
                } else {
                    lastAddedSale = new Sale(time, name, price, amount);
                    sales.add(lastAddedSale);
                }
            } catch (ParseException ex) {
                ex.printStackTrace();
                return new ArrayList<Sale>();
            }
        }
        Collections.reverse(sales);
        return sales;
    }

    private long calculateDate(String str) throws ParseException {
        DateFormat formatter = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
        Calendar c = Calendar.getInstance();
        str = c.get(Calendar.YEAR) + ":" + (c.get(Calendar.MONTH) + 1) + ":"
                + c.get(Calendar.DAY_OF_MONTH) + " " + str;
        Date date = formatter.parse(str);
        return date.getTime();
    }

    @Override
    public String toString() {
        return name;
    }

    @Override
    public boolean equals(Object other) {
        Stock otherStock = (Stock) other;
        return id == otherStock.id;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 13 * hash + id;
        return hash;
    }
}
